package cn.hamster3.hamsterworld;

import cn.hamster3.api.HamsterAPI;
import cn.hamster3.hamsterworld.command.*;
import cn.hamster3.hamsterworld.core.DataManager;
import cn.hamster3.hamsterworld.core.Message;
import cn.hamster3.hamsterworld.data.WorldData;
import cn.hamster3.hamsterworld.listener.MainListener;
import cn.hamster3.hamsterworld.thread.RealTime;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings("unused")
public final class HamsterWorld extends JavaPlugin {
    private static DataManager dataManager;
    private HashMap<String, CommandBase> commands;

    /**
     * 给其他插件使用的API
     *
     * @return API
     */
    public static DataManager getDataManager() {
        return dataManager;
    }

    @Override
    public void onEnable() {
        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 插件准备启动...");

        dataManager = new DataManager(this);
        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 准备注册监听器...");
        Bukkit.getPluginManager().registerEvents(new MainListener(dataManager), this);
        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 监听器注册完成!");

        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 准备注册命令...");
        commands = new HashMap<>();
        commands.put("add", new AddCommand(dataManager));
        commands.put("back", new BackCommand(dataManager));
        commands.put("create", new CreateCommand(dataManager));
        commands.put("rebuild", new RebuildCommand(dataManager));
        commands.put("remove", new RemoveCommand(dataManager));
        commands.put("tp", new TeleportCommand(dataManager));
        commands.put("reload", new ReloadCommand(dataManager));
        commands.put("info", new InfoCommand(dataManager));
        commands.put("list", new ListCommand(dataManager));
        commands.put("public", new PublicCommand(dataManager));
        commands.put("setSize".toLowerCase(), new SetSizeCommand(dataManager));
        commands.put("realTime".toLowerCase(), new RealTimeCommand(dataManager));
        commands.put("setSpawn".toLowerCase(), new SetSpawnCommand(dataManager));
        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 命令注册完成!");
        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 开始加载世界...");
        for (WorldData worldData : dataManager.getWorldData()) {
            try {
                dataManager.loadWorld(worldData);
                HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 加载了 " + worldData.getName());
            } catch (Exception e) {
                HamsterAPI.sendConsoleMessage("§c[HamsterWorld] 加载世界 %s 时出现了错误!", worldData.getName());
                e.printStackTrace();
            }
        }
        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 世界加载完成!");

        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 挂载 RealTime 组件中...");
        new RealTime(dataManager).runTaskTimer(this, 1200, 1200);
        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] ReadTime 组件挂载完成!");
        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 插件启动完成!");
    }

    @Override
    public void onDisable() {
        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 插件准备关闭...");
        if (dataManager != null) {
            dataManager.saveAllData();
        }
        HamsterAPI.sendConsoleMessage("§a[HamsterWorld] 插件关闭完成!");
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (args.length == 0) {
            sender.sendMessage("§a======================[ 仓鼠世界 ]======================");
            sender.sendMessage("§a/hw create                      - 创建一个新世界");
            sender.sendMessage("§a/hw back                        - 返回你的世界");
            sender.sendMessage("§a/hw setSpawn                    - 设置世界的出生点");
            sender.sendMessage("§a/hw rebuild                     - 重建你的世界§c§l（摧毁存档");
            sender.sendMessage("§a/hw public <on/off>             - 开启/关闭世界公开状态");
            sender.sendMessage("§a/hw add <玩家名>                - 允许玩家进入你的世界");
            sender.sendMessage("§a/hw remove <玩家名>             - 把玩家踢出你的世界");
            sender.sendMessage("§a/hw tp <世界名>                 - 传送到某个世界");
            if (sender.hasPermission("hw.admin")) {
                sender.sendMessage("§a/hw setSize <世界名> <大小>      - 设置世界边界大小");
                sender.sendMessage("§a/hw info <世界名>                - 查看世界设定");
                sender.sendMessage("§a/hw realTime <世界名> <on/off>   - 开启/关闭世界现实时间同步");
                sender.sendMessage("§a/hw reload                      - 重载插件");
            }
            sender.sendMessage("§a======================[ 仓鼠世界 ]======================");
            return true;
        }
        CommandBase commandBase = commands.get(args[0].toLowerCase());
        if (commandBase == null) {
            sender.sendMessage(Message.unknownCommand.toString());
            return true;
        }
        if (command.getPermission() != null && !sender.hasPermission(commandBase.getPermission())) {
            sender.sendMessage("§c你没有这个权限!");
            return true;
        }
        if (commandBase.isPlayerCommand() && !(sender instanceof Player)) {
            sender.sendMessage("§c这个命令只能由玩家执行!");
            return true;
        }
        commandBase.onCommand(sender, command, label, args);
        return true;
    }

    @Override
    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
        boolean isPlayer = sender instanceof Player;
        if (args.length == 1) {
            ArrayList<String> tab = new ArrayList<>();
            for (Map.Entry<String, CommandBase> entry : commands.entrySet()) {
                if (entry.getKey().toLowerCase().startsWith(args[0].toLowerCase())) {
                    continue;
                }
                if (entry.getValue().isPlayerCommand() && !isPlayer) {
                    continue;
                }
                if (entry.getValue().getPermission() != null && !sender.hasPermission(entry.getValue().getPermission())) {
                    continue;
                }
                tab.add(entry.getKey());
            }
            return tab;
        }
        CommandBase commandBase = commands.get(args[0].toLowerCase());
        if (commandBase == null) {
            return null;
        }
        return commandBase.onTabComplete(sender, command, alias, args);
    }
}
